package in.muton.edushare.wicket.models;

import in.muton.edushare.EduShareSession;

import org.apache.cayenne.DataObject;
import org.apache.cayenne.DataObjectUtils;
import org.apache.cayenne.ObjectId;
import org.apache.cayenne.PersistenceState;
import org.apache.cayenne.access.DataContext;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.wicket.model.IModel;

import com.edushare.common.exceptions.EduShareRuntimeException;
import com.edushare.common.orm.CayenneORMInterface;

public class CayenneModel<T> implements IModel<T> {
	private static Log log = LogFactory.getLog(CayenneModel.class);

	public CayenneModel(T obj) {
		setObject(obj);
	}

	public T getObject() {
		if (this.object == null) {
			if (this.objectId != null) {
				this.object = load(objectId);
				if (this.object == null) {
					throw new EduShareRuntimeException("Entity not found. Id: "
							+ this.objectId);
				}
			}
		}

		if (this.object != null
				&& ((DataObject) object).getPersistenceState() == PersistenceState.HOLLOW
				&& this.objectId != null) {
			this.object = load(this.objectId);
		}
		return this.object;
	}

	public void setObject(T object) {
		if (((DataObject) object).getPersistenceState() == PersistenceState.TRANSIENT) {
			this.objectId = null;
		} else {
			this.objectId = ((DataObject) object).getObjectId();
		}
		this.object = object;
	}

	public void detach() {
		if (this.object != null) {
			if (((DataObject) object).getPersistenceState() != PersistenceState.TRANSIENT) {
				this.objectId = ((DataObject) object).getObjectId();
				this.object = null;
			}
		}
	}

	@SuppressWarnings("unchecked")
	private T load(ObjectId objId) {
		DataContext ctx = ((CayenneORMInterface) EduShareSession.get()
				.getSessionORMInterface()).getDataContext();
		DataObject dobj = (DataObject) DataObjectUtils.objectForPK(ctx, objId);
		return (T) dobj;
	}

	private transient T object = null;
	private ObjectId objectId = null;
	private static final long serialVersionUID = 5320017712094929920L;
}
